package org.quadraspace.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.quadraspace.model.Event;
import org.quadraspace.model.Mote;
import org.quadraspace.model.MoteUtil;
import org.quadraspace.service.EventRepository;
import org.quadraspace.service.MoteRepository;

public class InMemoryMoteRepository implements MoteRepository, EventRepository {
	private int generatedId = 0;
	HashMap<String, Mote> registered = new HashMap<String, Mote>();
	HashMap<String, List<Event>> events = new HashMap<String, List<Event>>();

	public InMemoryMoteRepository() {
	}

	private boolean fake = false;

	public InMemoryMoteRepository(boolean _fake) {
		fake = _fake;
		if (fake) {
			registerMote(MoteUtil.generateFakeMoteWithID("fakeSensor"));
			registerMote(MoteUtil.generateFakeMoteWithID("dummySensor"));
		}
	}

	public void clear() {
		registered.clear();
	}

	public void registerMote(Mote toreg) {
		registered.put(toreg.getId(), toreg);
	}

	public Mote getMoteWithID(String id) {
		Mote toRet = registered.get(id);
		return toRet;
	}

	public List<Mote> getAllMotes() {
		return new ArrayList<Mote>(registered.values());
	}

	public synchronized String generateIdFor(Mote toAssignId) {
		return "QUADRA_" + (generatedId++);
	}

	public boolean deleteMoteWithId(String moteId) {
		return registered.remove(moteId) != null;
	}

	private List<Event> getOrCreateEvents(String id) {
		List<Event> toRet = events.get(id);
		if (toRet == null) {
			toRet = new ArrayList<Event>();
			if (fake) {
				toRet.add(new Event());
				toRet.add(new Event());
			}
			events.put(id, toRet);
		}
		return toRet;
	}

	@Override
	public void addEventForMoteWithID(String id, Event toAdd) {
		getOrCreateEvents(id).add(toAdd);
	}

	@Override
	public List<Event> getEventsForMoteWithId(String id) {
		return getOrCreateEvents(id);
	}

	@Override
	public List<Event> getEventsForMoteWithId(String id, long startmillis, long endmillis) {
		List<Event> toRet = new ArrayList<Event>();
		for (Event e : getOrCreateEvents(id)) {
			if (e.getTimestamp() >= startmillis && e.getTimestamp() <= endmillis) {
				toRet.add(e);
			}
		}
		return toRet;
	}
}
